import { defineStore } from 'pinia'
import emitter from '@/utils/eventBus'
import cache from "@/utils/cache"
import datetime from '@/utils/datetime'
// import reqNoToken from '@/api/reqNoToken'
import loginApi from '@/api/login'

const ADMIN_TOKEN = 'admin_token'
const ADMIN_REFRESH_TOKEN = 'admin_refresh_token'


const initState = () => {

    let tokenInfo = cache.info(ADMIN_TOKEN);
    let adminRefreshTokenInfo = cache.info(ADMIN_REFRESH_TOKEN);
    if (tokenInfo && tokenInfo.val) {
        setTimeout(() => {
            emitter.emit('TOKEN_SET', { token: tokenInfo.val })
        }, 500);
        // managerInfo().refresh()
    }
    return {
        token: tokenInfo ? tokenInfo.val : '',
        token_exp: tokenInfo ? tokenInfo.exp : 0,

        refresh_token: adminRefreshTokenInfo ? adminRefreshTokenInfo.val : '',
        refresh_token_exp: adminRefreshTokenInfo ? adminRefreshTokenInfo.exp : 0,

        isRefreshToken: false,

        managerInfo: {}
    }
}

export const Token = defineStore('token', {
    state: initState,

    actions: {

        // 用户进行登录，避免循环嵌套js
        userpwdLogin(loginData) {
            return new Promise((resolve, rej) => {
                loginApi.pwdLogin(loginData)
                    .then(res => {
                        let { data } = res;

                        this.setTokenInfo(data.jwt.token, data.jwt.exp * 1000)
                        this.setRefreshTokenInfo(data.refresh_token.token, data.refresh_token.exp * 1000)
                        resolve(data)
                    })
                    .catch(err => {
                        rej(err)
                    })
            })

        },

        setTokenInfo(token, exp) {
            this.token = token;
            this.token_exp = exp;
            cache.set(ADMIN_TOKEN, token, exp)
            setTimeout(() => {
                emitter.emit('TOKEN_SET', { token })

            }, 500);
        },

        setRefreshTokenInfo(token, exp) {
            this.refresh_token = token;
            this.refresh_token_exp = exp;
            cache.set(ADMIN_REFRESH_TOKEN, token, exp)
        },

        clearToken() {
            cache.remove(ADMIN_TOKEN);
            cache.remove(ADMIN_REFRESH_TOKEN);

            this.$patch(initState())
            setTimeout(() => {
                emitter.emit('TOKEN_SET', { token: '' })
            }, 500);
        },

        getValidToken() {
            if (this.token && this.token_exp > datetime.now()) {
                return this.token;
            }
            return ''
        },

        getToken() {
            return new Promise((resolve, rej) => {

                let validToken = this.getValidToken();
                if (validToken) {
                    return resolve({
                        token: validToken
                    });
                }
                if (this.refresh_token && this.refresh_token_exp > datetime.now()) {

                    if (this.isRefreshToken) {
                        // todo 重试
                        setTimeout(() => {
                            let _token = this.getValidToken();
                            if (_token) {
                                resolve({
                                    token: _token
                                });
                            } else {
                                rej({
                                    code: 102,
                                    msg: '请重试'
                                });
                            }
                        }, 3000);
                        return;
                    }
                    this.isRefreshToken = true;
                    // 刷新token可用
                    loginApi.refreshToken(this.refresh_token)
                        .then(res => {
                            this.isRefreshToken = false;
                            let { data } = res;

                            this.setTokenInfo(data.jwt.token, data.jwt.exp * 1000)
                            this.setRefreshTokenInfo(data.refresh_token.token, data.refresh_token.exp * 1000)
                            resolve({
                                token: data.jwt.token,
                            })
                        })
                        .catch(err => {
                            this.isRefreshToken = false;
                            rej(err);
                        })
                    return;
                }
                rej({
                    code: 101,
                    msg: '请重新登录'
                });
            })

        }
    }
})

export default Token